﻿using System;
using System.Drawing;
using System.Windows.Forms;
using DrawTools.Editor;
using DrawTools.ViewModels;

namespace DrawTools.Forms
{
  public partial class PropertiesForm : Form
  {
    private readonly IDrawingCanvas _canvas;
    private readonly EditorTheme _theme;

    private bool _suppressEvents;

    private PropertiesFormViewModel _viewModel;

    public PropertiesForm(IDrawingCanvas canvas, EditorTheme theme)
    {
      _canvas = canvas;
      _theme = theme;
      InitializeComponent();
      InitComboBoxes();
    }

    public void SetViewModel(PropertiesFormViewModel viewModel)
    {
      _viewModel = viewModel;
      ApplyViewModel();
    }

    #region Initialization

    private void InitComboBoxes()
    {
      _suppressEvents = true;

      borderColorSelector.Palette = _theme.Colors;
      backColorSelector.Palette = _theme.Colors;
      textColorSelector.Palette = _theme.Colors;
      cboLineWidth.DataSource = _theme.BorderWidths;

      _suppressEvents = false;
    }

    private void ApplyViewModel()
    {
      _suppressEvents = true;

      pnlLayers.Visible = _viewModel != null;
      pnlGeneral.Visible = _viewModel != null;
      lblSelectionInfo.Visible = _viewModel == null;

      if (_viewModel == null)
      {
        cboLineWidth.SelectedIndex = -1;
        borderColorSelector.BackColor = Color.White;
        backColorSelector.BackColor = Color.White;
        return;
      }

      pnlBackColor.Visible = _viewModel.IsBackColorPartVisible;
      pnlArrows.Visible = _viewModel.IsArrowPartVisible;
      rdoNone.Visible = !_viewModel.IsArrowPartVisible;
      pnlText.Visible = _viewModel.IsTextPartVisible;

      Text = _viewModel.Name;

      //Canvas Rectangle and Ellipse
      cboLineWidth.SelectedItem = _viewModel.BorderWidth;
      borderColorSelector.BackColor = _viewModel.BorderColor;

      rdoNone.Checked = _viewModel.LineType == LineType.None;
      rdoSolid.Checked = _viewModel.LineType == LineType.Solid;
      rdoDash.Checked = _viewModel.LineType == LineType.Dash;
      rdoDot.Checked = _viewModel.LineType == LineType.Dot;

      backColorSelector.BackColor = _viewModel.BackColor;
      opacityControl.Value = _viewModel.BackgroundOpacity;

      //Canvas Line
      chkArrowRight.Checked = _viewModel.IsArrowAtEnd ?? false;
      chkArrowLeft.Checked = _viewModel.IsArrowAtStart ?? false;

      //Canvas Text
      textColorSelector.BackColor = _viewModel.TextColor;

      chkBold.Checked = _viewModel.IsBold ?? false;
      chkItalic.Checked = _viewModel.IsItalic ?? false;
      chkUnderline.Checked = _viewModel.IsUnderline ?? false;

      rdoTextLeft.Checked = _viewModel.TextAlignment == StringAlignment.Near;
      rdoTextCenter.Checked = _viewModel.TextAlignment == StringAlignment.Center;
      rdoTextRight.Checked = _viewModel.TextAlignment == StringAlignment.Far;

      _suppressEvents = false;
    }

    #endregion

    #region Event Handlers

    private void OnSendToBack(object sender, EventArgs e)
    {
      _canvas.GraphicsList.MoveSelectionToBack();
      _canvas.Refresh();
    }

    private void OnBringToFront(object sender, EventArgs e)
    {
      _canvas.GraphicsList.MoveSelectionToFront();
      _canvas.Refresh();
    }

    private void OnBorderColorChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      _viewModel.BorderColor = borderColorSelector.BackColor;
      _canvas.Refresh();
    }

    private void OnLineTypeChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      if (sender == rdoNone && rdoNone.Checked)
        _viewModel.LineType = LineType.None;

      if (sender == rdoSolid && rdoSolid.Checked)
        _viewModel.LineType = LineType.Solid;

      if (sender == rdoDash && rdoDash.Checked)
        _viewModel.LineType = LineType.Dash;

      if (sender == rdoDot && rdoDot.Checked)
        _viewModel.LineType = LineType.Dot;

      _canvas.Refresh();
    }

    private void OnTextSizeDecreased(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      if (_viewModel.FontSize <= _theme.FontSizeMin)
        return;

      _viewModel.FontSize -= _theme.FontSizeStep;

      _canvas.Refresh();
    }

    private void OnTextSizeIncreased(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      if (_viewModel.FontSize >= _theme.FontSizeMax)
        return;

      _viewModel.FontSize += _theme.FontSizeStep;

      _canvas.Refresh();
    }

    private void OnTextAlignmentChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      if (rdoTextLeft.Checked)
      {
        _viewModel.TextAlignment = StringAlignment.Near;
      }
      else if (rdoTextCenter.Checked)
      {
        _viewModel.TextAlignment = StringAlignment.Center;
      }
      else if (rdoTextRight.Checked)
      {
        _viewModel.TextAlignment = StringAlignment.Far;
      }

      _canvas.Refresh();
    }

    private void OnBackColorChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      _viewModel.BackColor = backColorSelector.BackColor;
      _canvas.Refresh();
    }

    private void OnTextColorChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      _viewModel.TextColor = textColorSelector.BackColor;
      _canvas.Refresh();
    }

    private void OnBorderWidthChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      _viewModel.BorderWidth = (int)cboLineWidth.SelectedValue;
      _canvas.Refresh();
    }

    private void OnArrowChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      _viewModel.IsArrowAtStart = chkArrowLeft.Checked;
      _viewModel.IsArrowAtEnd = chkArrowRight.Checked;
      _canvas.Refresh();
    }

    private void OnBackgroundOpacityChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      _viewModel.BackgroundOpacity = opacityControl.Value;
      _canvas.Refresh();
    }

    private void OnFontStyleChanged(object sender, EventArgs e)
    {
      if (_suppressEvents)
        return;

      _viewModel.IsBold = chkBold.Checked;
      _viewModel.IsItalic = chkItalic.Checked;
      _viewModel.IsUnderline = chkUnderline.Checked;
      _canvas.Refresh();
    }

    #endregion
  }
}